import {asyncRoutes, constantRoutes} from '@/router'
import {AuthorityCode} from '@/api/Enums'

/**
 * Use meta.role to determine if the current user has permission
 * @param authorityList {String[]} {AuthorityCode}
 * @param route {Route}
 */
function hasPermission(authorityList, route) {
  if (route.meta && route.meta.roles) {
    return authorityList.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes {Route[]} asyncRoutes
 * @param authorityList {String[]}
 */
export function filterAsyncRoutes(routes, authorityList) {
  return routes.map(route => {
    const tmp = {...route}
    if (hasPermission(authorityList, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, authorityList)
      }
      return tmp
    }
    return null
  }).filter(Boolean)
}

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.routes = constantRoutes.concat(routes)
    state.addRoutes = routes
  }
}

const actions = {
  /**
   * 生成异步挂载路由
   * @param commit
   * @param authorityList {String[]}
   * @returns {Promise<unknown>}
   */
  generateRoutes({commit}, authorityList) {
    return new Promise(resolve => {
      let accessedRoutes
      if (authorityList.includes(AuthorityCode.ROLE_ADMIN.key)) {
        accessedRoutes = asyncRoutes || []
      } else {
        accessedRoutes = filterAsyncRoutes(asyncRoutes, authorityList)
      }
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}
